package com.qianya.weishi_server.utils;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lc
 * @date 2021/4/27 19:13
 */
public class DateTimeUtil {

    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};


    // 返回时间格式如：2020-02-17 00:00:00
    public static String getStartOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).format(calendar.getTime());
    }

    // 返回时间格式如：2020-02-19 23:59:59
    public static String getEndOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).format(calendar.getTime());
    }

    public static String getYearMothDayHour() {
        Calendar now = Calendar.getInstance();
        return new SimpleDateFormat("yyyyMMddHH").format(now.getTime());
    }

    //获取时分秒的时间戳
    public static long getTimeStampHms(Date dataTmp) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        String dateString = simpleDateFormat.format(dataTmp);
        Date dates = simpleDateFormat.parse(dateString);
        long ts = dates.getTime();
        return ts;
    }

    /**
     * 获取一个时间段之内的天数
     *
     * @param cntDateBeg
     * @param cntDateEnd
     * @return
     */
    public static List<String> addDates(String cntDateBeg, String cntDateEnd) {
        List<String> list = new ArrayList<>();
        //拆分成数组
        String[] dateBegs = cntDateBeg.split("-");
        String[] dateEnds = cntDateEnd.split("-");
        //开始时间转换成时间戳
        Calendar start = Calendar.getInstance();
        start.set(Integer.valueOf(dateBegs[0]), Integer.valueOf(dateBegs[1]) - 1, Integer.valueOf(dateBegs[2]));
        long startTime = start.getTimeInMillis();
        //结束时间转换成时间戳
        Calendar end = Calendar.getInstance();
        end.set(Integer.valueOf(dateEnds[0]), Integer.valueOf(dateEnds[1]) - 1, Integer.valueOf(dateEnds[2]));
        Long endTime = end.getTimeInMillis();
        //定义一个一天的时间戳时长
        Long oneDay = 1000 * 60 * 60 * 24L;
        Long time = startTime;
        //循环得出
        while (time <= endTime) {
            list.add(new SimpleDateFormat(YYYY_MM_DD).format(new Date(time)));
            time += oneDay;
        }
        return list;
    }

    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    public static String getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat(YYYY_MM_DD);
        return format.format(today);
    }

    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    public static Date getPastDateTime(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        return calendar.getTime();
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     */
    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * 将时间格式转换为字符串
     */
    public static String dateToStr(Date date, boolean second) {
        SimpleDateFormat formatter;
        if (second) {
            formatter = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        } else {
            formatter = new SimpleDateFormat(YYYY_MM_DD);
        }

        return formatter.format(date);
    }

    /**
     * 获取固定天数后的日期
     *
     * @param day 天数
     * @return
     */
    public static Date getFixedDayDate(int day) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, day);
//        SimpleDateFormat sdf1 = new SimpleDateFormat(YYYY_MM_DD);
        return cal.getTime();
    }

    public static Date setTimeZero(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将时分秒,毫秒域清零
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }


    public static int getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    //isRange，是否为范围，是则少计算一天
    public static String getSkipDayStr(String dateString, int skipCount, boolean isRange, int type) {
        if (dateString == null) {
            return null;
        }
        SimpleDateFormat sf = new SimpleDateFormat(YYYY_MM_DD);
        Date date = null;
        try {
            date = sf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        } else {
            return null;
        }

        if (isRange) {
            if (type == Calendar.DATE) {
                skipCount -= 1;
            } else if (type == Calendar.MONTH) {
                calendar.add(Calendar.DATE, -1);
            }
        }
        calendar.add(type, skipCount);
        return sf.format(calendar.getTime());
    }

    public static Date getSkipDay(Date date, int skipCount, boolean isRange, int type) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        } else {
            return null;
        }
        if (isRange) {
            skipCount -= 1;
        }
        calendar.add(type, skipCount);
        return calendar.getTime();
    }

    public static String getSkipDayToStr(Date date, int skipCount, boolean isRange, int type) {
        SimpleDateFormat sf = new SimpleDateFormat(YYYY_MM_DD);
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        } else {
            return null;
        }
        if (isRange) {
            if (type == Calendar.DATE) {
                skipCount -= 1;
            } else if (type == Calendar.MONTH) {
                calendar.add(Calendar.DATE, -1);
            }
        }
        calendar.add(type, skipCount);
        return sf.format(calendar.getTime());
    }

    public static String getNextDayStr(String dateString, boolean isRange) {
        return getSkipDayStr(dateString, 1, isRange, Calendar.DATE);
    }

    public static Date getNextDay(Date date, boolean isRange) {
        return getSkipDay(date, 1, isRange, Calendar.DATE);
    }


    public static String getSkipWeekDayStr(String dateString, boolean isRange, int skipWeekCount) {
        return getSkipDayStr(dateString, 7 * skipWeekCount, isRange, Calendar.DATE);
    }

    public static String getNextMonthDayStr(String dateString, boolean isRange) {
        return getSkipDayStr(dateString, 1, isRange, Calendar.MONTH);
    }


    public static String getSkipDayToStr(Date date, boolean isRange, int skipDayCount) {
        return getSkipDayToStr(date, skipDayCount, isRange, Calendar.MONTH);
    }

    public static Date getSkipMonthDay(Date date, boolean isRange, int skipMonthCount) {
        return getSkipDay(date, skipMonthCount, isRange, Calendar.MONTH);
    }

    public static String getLastDayStr(String dateString) {
        return getSkipDayStr(dateString, -1, false, Calendar.DATE);
    }

    //获取号数
    public static int getDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    public static Date getThisWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    public static Date getLastWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getThisWeekMonday(date));
        cal.add(Calendar.DATE, -7);
        return cal.getTime();
    }

    public static Date getNextWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getThisWeekMonday(date));
        cal.add(Calendar.DATE, 7);
        return cal.getTime();
    }

    /**
     * 得到两个日期相差的天数
     */
    public static int getBetweenDay(Date date1, Date date2) {
        Calendar d1 = Calendar.getInstance();
        d1.setTime(date1);
        Calendar d2 = Calendar.getInstance();
        d2.setTime(date2);
        int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
        int y2 = d2.get(Calendar.YEAR);
        if (d1.get(Calendar.YEAR) != y2) {
            do {
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
                d1.add(Calendar.YEAR, 1);
            } while (d1.get(Calendar.YEAR) != y2);
        }
        return days;
    }

    /**
     * 根据当前年份获取年份下所有月份
     *
     * @param
     * @return
     */
    public static ArrayList<String> getYearFullMonth() {
        Calendar c = Calendar.getInstance();
        String[] array = new String[12];
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM);
        Calendar cal = Calendar.getInstance();
        // 获取当前时间的年份
        cal.set(Calendar.YEAR, c.get(Calendar.YEAR));
        cal.set(Calendar.MONTH, 0);
        for (int i = 0; i < 12; i++) {
            array[i] = sdf.format(cal.getTime());
            cal.add(Calendar.MONTH, 1);
        }
        //asList返回值虽然是ArrayList但不是java.util.ArrayList,而是Arrays内部的一个私有静态内部类，它的长度是固定的，不存在所谓的add()添加元素等方法
        return new ArrayList<>(Arrays.asList(array));
    }

    public static String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }
}
